package com.ray.service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.ray.bean.ApplyRepairFormBean;
import com.ray.bean.CompanyMaterialCountBean;
import com.ray.bean.CompanyMaterialTableBean;
import com.ray.bean.CustomerBean;
import com.ray.bean.DatatablesViewPageBean;
import com.ray.bean.FeedOrderDetailBean;
import com.ray.bean.FeedUseMaterialCountBean;
import com.ray.bean.FinishStockBean;
import com.ray.bean.OtherWarehouseBean;
import com.ray.bean.PurchaseDetailBean;
import com.ray.bean.PurchaseOrderDetailBean;
import com.ray.bean.QueryOrderPageBean;
import com.ray.bean.SearchWhereBean;
import com.ray.bean.UserBean;
import com.ray.bean.WarehouseInOutDetailBean;
import com.ray.exception.ServiceException;
import com.ray.mapper.ApplyRepairFormMapper;
import com.ray.mapper.CompanyMaterialMapper;
import com.ray.mapper.DingTalkMapper;
import com.ray.mapper.FeedUseMaterialCountMapper;
import com.ray.mapper.OrderMapper;
import com.ray.mapper.OtherWarehouseMapper;
import com.ray.pojo.MyUser;
import com.ray.util.RedirectUrlUtil;
import com.ray.util.RequestUtil;
import com.ray.util.ReturnStringUtil;
import com.ray.util.StringUtil;

import net.sf.json.JSONArray;

@Service
public class OtherWarehouseService {
	@Autowired
	OtherWarehouseMapper otherWarehouseMapper;
	@Autowired
	WorkshopService workshopService;
	@Autowired
	UserService userService;
	@Autowired
	CompanyMaterialMapper companyMaterialMapper;
	@Autowired
	DingTalkMapper dingTalkMapper;
	@Autowired
	BasicDataService basicDataService;
	@Autowired
	OrderMapper orderMapper;
	@Autowired
	FeedUseMaterialCountMapper feedUseMaterialCountMapper;
	@Autowired
	OrderService orderService;
	@Autowired
	CompanyMaterialService companyMaterialService;
	@Autowired 
	ApplyRepairFormMapper applyRepairFormMapper;
	@Autowired
	ApprovalService approvalService;
	@Autowired
	WarehouseService warehouseService;
	@Autowired
	CompanyMaterialCountService companyMaterialCountService;

	/**
	 * @author natelu
	 * 通过集合插入其他仓库数据
	 * @param otherWarehouseBeanList
	 */
	public void insertOtherWarehouseByList(List<OtherWarehouseBean> otherWarehouseBeanList) {
		otherWarehouseMapper.insertOtherWarehouseByList(otherWarehouseBeanList);
	}

	/**
	 * @author nate
	 * 通过报工删除其他仓库记录
	 * @param otherIdList
	 */
	public void deleteOtherWarehouseByIdList(List<String> idList) {
		otherWarehouseMapper.deleteOtherWarehouseByIdList(idList);
	}

	/**
	 * @author nate
	 * 修改
	 * @param otherWarehouseBean
	 */
	public void updateOtherWarehouseByBean(OtherWarehouseBean otherWarehouseBean) {
		otherWarehouseMapper.updateOtherWarehouseByBean(otherWarehouseBean);
	}
	
	/**
	 * @throws CloneNotSupportedException 
	 * @throws ServiceException 
	 * 审批OtherWarehouse状态
	* @date 2018年5月30日 下午3:52:23 
	* @author 李斌
	* @return void 
	* @throws
	 */
	public String updateOtherWarehouseStatusById(Map<String, Object> map,int status) throws ServiceException, CloneNotSupportedException {
		//判断是否重复操作
		OtherWarehouseBean otherWarehouseBean = otherWarehouseMapper.getOtherWarehouseById(map);
		if(otherWarehouseBean.getStatus()!=0) {
			throw new ServiceException("该出入库单已经审核"); 
		} 
		//判断审核权限
		Map<String, Object> approvalParam = new HashMap<String,Object>();
		approvalParam.put("type","6"); 
		approvalParam.put("loginUserId", map.get("loginUserId"));
		approvalParam.put("loginCompany", map.get("loginCompany"));
		List<String> userIds = approvalService.getApprovalIdByLoginId(approvalParam);
		int isApproval = 0;
		if(userIds !=null && userIds.size()>0) {
			for(String createUserId:userIds) {
				if(createUserId.equals(otherWarehouseBean.getCreateUser())) {
					isApproval = 1;
					break;
				}
			}
		}
		if(isApproval==0) { 
			throw new ServiceException("您暂无权限审核此出入库单!");
		} 
		
		//审批报工
		String finishId=map.get("id").toString();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		map.put("time", sdf.format(new Date()));
		Object source = map.get("source");
		if(source==null) {
			throw new ServiceException("source为空异常");
		}
		String bodyMessage = "";
		String feedDetailId = "";
		String pageType = null;
		if(status==1) {
			if(source.toString().equals("1")) {
				map.put("otherId", map.get("id"));
				if(map.get("approvalReason")==null||map.get("approvalReason").toString().equals("")) {
					map.put("approvalReason", status==1?"出入库审核":"出入库退回");
				}
				//审核出入库信息 
				otherWarehouseMapper.updateOtherWarehouseStatusById(map);
				map.remove("id");
				map.put("name", map.get("loginUserName"));
				workshopService.approvalReportByOtherId(map);
				bodyMessage = "报工出入库审批";
				pageType = RedirectUrlUtil.queryWarehouse;
			}else if(source.toString().equals("2") || source.toString().equals("3")) {
				if(source.toString().equals("2")) {
					 //订单采购单出库后
					if(otherWarehouseBean.getInOutType()==2 && status==1) {
						//出库数量
						//Double outCount = otherWarehouseBean.getCount();
						BigDecimal bigOutCount = new BigDecimal(otherWarehouseBean.getCount().toString());
						//采购投料对应表明细id
						String purchaseDetailId = otherWarehouseBean.getPurchaseDetailId();
						Map<String,Object> purchaseMap = new HashMap<String,Object>();
						purchaseMap.put("purchaseDetailId", purchaseDetailId);
						purchaseMap.put("loginCompany", map.get("loginCompany"));
						//查询投料单,通过采购投料对应表id查询
						List<FeedOrderDetailBean> feedOrderDetailBeans = orderMapper.getFeedOrderDetailByPurchaseFeedDetailId(purchaseMap);
						if(feedOrderDetailBeans==null ||feedOrderDetailBeans.size()==0 || feedOrderDetailBeans.size()>1) {
							throw new ServiceException("投料单明细为空或多条异常");
						} 
						//投料数
						BigDecimal bigFeedCount = new BigDecimal(feedOrderDetailBeans.get(0).getFeedCount().toString());
						feedDetailId = feedOrderDetailBeans.get(0).getId();
						purchaseMap.put("feedDetailId",feedOrderDetailBeans.get(0).getId());
						//通过投料单id查询占用数
						List<FeedUseMaterialCountBean> feedUseMaterialCountBeans = feedUseMaterialCountMapper.getFeedUseMaterialCountByFeedDetailId(purchaseMap);
						//如果有占用数,才有后续的操作
						if(feedUseMaterialCountBeans!=null && feedUseMaterialCountBeans.size()>0) {
							BigDecimal bigFeedUseMaterialCount = new BigDecimal(feedUseMaterialCountBeans.get(0).getFeedUseCount().toString());
							//当前投料单出库信息(原料仓的)
							List<WarehouseInOutDetailBean> warehouseInOutDetailBeans =  orderMapper.getWarehouseInOutDetailByFeedDetailId(purchaseMap);
							//double materialOutCount =0;
							BigDecimal bigMaterialOutCount = new BigDecimal("0.0");
							for(WarehouseInOutDetailBean warehouseInOutDetailBean:warehouseInOutDetailBeans) {
								if(warehouseInOutDetailBean.getCount()==null) {
									throw new ServiceException("关联出库数量为空异常");
								}
								//materialOutCount+=warehouseInOutDetailBean.getCount();
								BigDecimal materialOutCount = new BigDecimal(warehouseInOutDetailBean.getCount().toString());
								bigMaterialOutCount = bigMaterialOutCount.add(materialOutCount);
							} 
							//当前投料单出库信息(其他仓位的) 
							double otherOutCount =  otherWarehouseMapper.getOtherWarehouseByPurchaseId(purchaseMap);
							BigDecimal bigOtherOutCount = new BigDecimal(otherOutCount+"");
							//投料数-其他仓库出库数-原料仓出库数-当前要出库的数量小于占用数
							bigFeedCount.subtract(bigOtherOutCount).subtract(bigMaterialOutCount).subtract(bigOutCount).subtract(bigFeedUseMaterialCount);
							if(bigFeedCount.subtract(bigOtherOutCount).subtract(bigMaterialOutCount).subtract(bigOutCount).subtract(bigFeedUseMaterialCount).doubleValue()<0) {
								feedUseMaterialCountBeans.get(0).setFeedUseCount(bigFeedCount.subtract(bigOtherOutCount).subtract(bigMaterialOutCount).subtract(bigOutCount).doubleValue());
								int feedUseRow = feedUseMaterialCountMapper.updateFeedUseCount(feedUseMaterialCountBeans.get(0));
								if(feedUseRow<1) {
									throw new ServiceException("消除占用数失败");
								}
							}
						}
						//将采购单明细id转换为投料单明细id
						otherWarehouseBean.setPurchaseDetailId(feedOrderDetailBeans.get(0).getId());
					}
				} 
			}else {
				throw new ServiceException("审核失败,source出错");
			}
			//审核出入库信息 
			Object warehouse = map.get("warehouse");
			if(warehouse==null) {
				throw new ServiceException("仓库为空异常");
			}
			bodyMessage = warehouse.toString()+"出入库审批";
			pageType = RedirectUrlUtil.queryWarehouse;
			otherWarehouseMapper.updateOtherWarehouseStatusById(map);
		}else {
			if(source.toString().equals("1")) {
				map.put("otherId", map.get("id"));
				if(map.get("approvalReason")==null||map.get("approvalReason").toString().equals("")) {
					map.put("approvalReason", status==1?"出入库审核":"出入库退回");
				}
				//审核出入库信息 
				otherWarehouseMapper.updateOtherWarehouseStatusById(map);
				map.remove("id");
				map.put("name", map.get("loginUserName"));
				workshopService.approvalReportByOtherId(map);
				bodyMessage = "报工出入库审批";
				pageType = RedirectUrlUtil.queryWarehouse;
			}else if(source.equals("2")) {//订单采购单
				if(otherWarehouseBean.getInOutType()==1) {
					List<PurchaseOrderDetailBean> list=new ArrayList<PurchaseOrderDetailBean>();
					PurchaseOrderDetailBean podb=companyMaterialMapper.getPurchaseOrderDetailById(otherWarehouseBean.getPurchaseDetailId());
					BigDecimal podbInCount = new BigDecimal(podb.getInCount().toString());
					BigDecimal count = new BigDecimal(otherWarehouseBean.getCount().toString());
					podb.setInCount(podbInCount.subtract(count).doubleValue());
					podb.setIsFinish(0);
					list.add(podb);
					companyMaterialMapper.updatePurchaseOrderDetail(list);
				}else if(otherWarehouseBean.getInOutType()==2) {
					  Map<String,Object> purchaseMap = new HashMap<String,Object>();
					  purchaseMap.put("loginCompany",map.get("loginCompany"));
					  purchaseMap.put("purchaseDetailId", otherWarehouseBean.getPurchaseDetailId());
					  List<FeedOrderDetailBean> feedOrderDetailBeans = orderMapper.getFeedOrderDetailByPurchaseFeedDetailId(purchaseMap);
					  FeedOrderDetailBean feedOrderDetailBean = null; 
					  if(feedOrderDetailBeans!=null && feedOrderDetailBeans.size()>0) {
						  if(feedOrderDetailBeans.size()>1) { 
							  throw new ServiceException("查出两条库存信息异常");
						  }
						  feedOrderDetailBean = feedOrderDetailBeans.get(0);
					  }else {
						  throw new ServiceException("无库存数据异常");
					  }
					  Double count = 0.0;
					  if(otherWarehouseBean.getCount()!=null) {
						  count = otherWarehouseBean.getCount();
					  }
					  BigDecimal receiveCount = new BigDecimal(feedOrderDetailBean.getReceiveCount().toString());
					  BigDecimal bigCount = new BigDecimal(count.toString());
					  BigDecimal bigFeedCount = new BigDecimal(feedOrderDetailBean.getFeedCount().toString());
					  //要修改的投料单信息
					  List<FeedOrderDetailBean> feedList=new ArrayList<FeedOrderDetailBean>();
					  //通过出库数据查找投料单明细
					  feedOrderDetailBean.setReceiveCount(receiveCount.subtract(bigCount).doubleValue());
					  if(receiveCount.subtract(bigCount).subtract(bigFeedCount).doubleValue()==0) {
						  feedOrderDetailBean.setIsReceiveFinish(1);
					  }else {
						  feedOrderDetailBean.setIsReceiveFinish(0);
					  } 
					  feedList.add(feedOrderDetailBean);
					  purchaseMap.put("feedList", feedList);
					  companyMaterialMapper.updateFeedOrderDetailReceive(purchaseMap);
				} 
			}else if(source.equals("3")) {//库存采购单
				if(otherWarehouseBean.getInOutType()==1) {
					PurchaseDetailBean podb=companyMaterialMapper.getPurchaseDetailById(otherWarehouseBean.getPurchaseDetailId());
					BigDecimal bigInCount = new BigDecimal(podb.getInCount().toString());
					BigDecimal count= new BigDecimal(otherWarehouseBean.getCount().toString());
					podb.setInCount(bigInCount.subtract(count).doubleValue());
					podb.setIsFinish(0);
				    companyMaterialMapper.updatePurchaseDetailOne(podb);
				}
			}else { 
				throw new ServiceException("无可退回的source类型异常");
			}
		}
		//审核出入库信息 
		Object warehouseObj = map.get("warehouse");
		if(warehouseObj==null) {
			throw new ServiceException("仓库为空异常");
		}
		bodyMessage = warehouseObj.toString()+"出入库审批";
		pageType = RedirectUrlUtil.queryWarehouse;
		otherWarehouseMapper.updateOtherWarehouseStatusById(map);
		UserBean userBean = userService.getUserByName(map);
		
		//成品仓 natelu
//		String  warehouse = map.get("warehouse").toString();
		//如果是成品仓
		if("成品仓".equals(warehouseObj.toString())) {
			Map finishMap=new HashMap<String,String>();
			finishMap.put("loginCompany", map.get("loginCompany").toString());
			finishMap.put("id", finishId);
			otherWarehouseBean=otherWarehouseMapper.getOtherWarehouseById(finishMap);
			//如果是出库,判断订单是否完成
			if(otherWarehouseBean.getInOutType()==2) { 
				checkOrderFinish(otherWarehouseBean.getOrderId(),otherWarehouseBean.getCount());
			}
		}
		//审核通过并且是投料单领料
		if(status == 1 && otherWarehouseBean.getSource()==2 && otherWarehouseBean.getInOutType()==2) {
			/**
			 * 投料单出库,审核通过后交接至车间
			 * 李斌
			 */ 
			map.put("feedDetailId", feedDetailId);
			ApplyRepairFormBean applyRepairFormBean = applyRepairFormMapper.getApplyByFeedDetailId(map);
			if(applyRepairFormBean!=null) {
				if(applyRepairFormBean.getType()==1) {
					return "损耗的申补单无需交接车间"; 
				}
			}
			
			/** 
			 * 投料单出库,审核通过后交接至车间
			 * 李斌  
			 */
			MyUser myUser = new MyUser();
			myUser.setCompany(map.get("loginCompany").toString());
			myUser.setDeptId(map.get("loginUserDeptId").toString());
			myUser.setUserId(map.get("loginUserId").toString());
			myUser.setUserName(map.get("loginUserName").toString());
			WarehouseInOutDetailBean warehouseInOutDetailBean = new WarehouseInOutDetailBean();
			warehouseInOutDetailBean.setId(otherWarehouseBean.getId());
			warehouseInOutDetailBean.setCount(otherWarehouseBean.getCount());
			warehouseInOutDetailBean.setMaterialCode(otherWarehouseBean.getMaterialCode());
			warehouseInOutDetailBean.setWorkShopId(otherWarehouseBean.getWorkShopId());
			warehouseInOutDetailBean.setFeedOrder(otherWarehouseBean.getPurchaseDetailId());
			String reportJSONStr =  companyMaterialService.getReportDataByWarehouse(warehouseInOutDetailBean,myUser,sdf.format(new Date()));
			String resultMessage = workshopService.insertReport(reportJSONStr, null, myUser);
			 
			//判断是否报工成功 
			if(resultMessage.indexOf(ReturnStringUtil.REPORT_SUCCESS)<0) {
				throw new ServiceException("领料单出库审核交接至车间异常");
			} 
		}
		
		return workshopService.sendApprovalStatusMassage(status, userBean.getId(), map.get("loginUserName").toString(),bodyMessage, pageType);
		
	}
	
	/**
	 * @throws ServiceException 
	 * 删除出入库信息
	* @date 2018年5月30日 下午4:17:58 
	* @author 李斌
	* @return void 
	* @throws  
	 */
	public void deleteOtherWarehouseById(Map<String, Object> map) throws ServiceException {
		if(map.get("id")!=null) {
			if(map.get("source")==null) {
				throw new ServiceException("source为空异常");
			}
			String source = map.get("source").toString();
			OtherWarehouseBean otherWarehouseBean = otherWarehouseMapper.getOtherWarehouseById(map);
			if(otherWarehouseBean.getStatus()!= 0) {
				throw new ServiceException("该出入库数已审核,无法删除");
			} 
			if(source.equals("1")) {
				otherWarehouseMapper.deleteOtherWarehouseById(map);
				workshopService.deleteReportByOtherId(map.get("id").toString());
			}else if(source.equals("2")) {//订单采购单
				if(otherWarehouseBean.getInOutType()==1) {
					List<PurchaseOrderDetailBean> list=new ArrayList<PurchaseOrderDetailBean>();
					PurchaseOrderDetailBean podb=companyMaterialMapper.getPurchaseOrderDetailById(otherWarehouseBean.getPurchaseDetailId());
					//采购单入库数
					BigDecimal bigInCount = new BigDecimal(podb.getInCount().toString());
					//删除数量
					BigDecimal bigOtherCount = new BigDecimal(otherWarehouseBean.getCount().toString());
					podb.setInCount(bigInCount.subtract(bigOtherCount).doubleValue());
					podb.setIsFinish(0);
					list.add(podb);
					companyMaterialMapper.updatePurchaseOrderDetail(list);
				}else if(otherWarehouseBean.getInOutType()==2) {
					  Map<String,Object> purchaseMap = new HashMap<String,Object>();
					  purchaseMap.put("loginCompany",map.get("loginCompany"));
					  purchaseMap.put("purchaseDetailId", otherWarehouseBean.getPurchaseDetailId());
					  List<FeedOrderDetailBean> feedOrderDetailBeans = orderMapper.getFeedOrderDetailByPurchaseFeedDetailId(purchaseMap);
					  FeedOrderDetailBean feedOrderDetailBean = null; 
					  if(feedOrderDetailBeans!=null && feedOrderDetailBeans.size()>0) {
						  if(feedOrderDetailBeans.size()>1) { 
							  throw new ServiceException("查出两条库存信息异常");
						  }
						  feedOrderDetailBean = feedOrderDetailBeans.get(0);
					  }else {
						  throw new ServiceException("无库存数据异常");
					  }
					  BigDecimal bigCount = new BigDecimal("0.0");
					  if(otherWarehouseBean.getCount()!=null) {
						  bigCount = bigCount.add(new BigDecimal(otherWarehouseBean.getCount().toString()));
					  }
					  //要修改的投料单信息
					  List<FeedOrderDetailBean> feedList=new ArrayList<FeedOrderDetailBean>();
					  //通过出库数据查找投料单明细
					  BigDecimal bigFeedReceiveCount = new BigDecimal(feedOrderDetailBean.getReceiveCount().toString());
					  BigDecimal bigFeedCount = new BigDecimal(feedOrderDetailBean.getFeedCount().toString());
					  feedOrderDetailBean.setReceiveCount(bigFeedReceiveCount.subtract(bigCount).doubleValue());
					  if(bigFeedReceiveCount.subtract(bigCount).subtract(bigFeedCount).doubleValue()==0) {
						  feedOrderDetailBean.setIsReceiveFinish(1);
					  }else {
						  feedOrderDetailBean.setIsReceiveFinish(0);
					  } 
					  feedList.add(feedOrderDetailBean);
					  purchaseMap.put("feedList", feedList);
					  companyMaterialMapper.updateFeedOrderDetailReceive(purchaseMap);
				}
				otherWarehouseMapper.deleteOtherWarehouseById(map);
			}else if(source.equals("3")) {//库存采购单
				if(otherWarehouseBean.getInOutType()==1) {
					PurchaseDetailBean podb=companyMaterialMapper.getPurchaseDetailById(otherWarehouseBean.getPurchaseDetailId());
					//采购单入库数
					BigDecimal bigInCount = new BigDecimal(podb.getInCount().toString());
					//删除数量
					BigDecimal bigOtherCount = new BigDecimal(otherWarehouseBean.getCount().toString());
					podb.setInCount(bigInCount.subtract(bigOtherCount).doubleValue());
					podb.setIsFinish(0);
				    companyMaterialMapper.updatePurchaseDetailOne(podb);
				}
			    otherWarehouseMapper.deleteOtherWarehouseById(map);
			}else {
				throw new ServiceException("无可删除的source类型异常");
			}
			
		}else {
			throw new ServiceException("otherId为空");
		}
		
	}
	
	/**
	 * 修改source为2或3的出入库
	* @date 2018年6月15日 上午8:21:45 
	* @author 李斌
	* @return void 
	* @throws
	 */
	public void updateOtherWarehouseByOrder(Map<String, Object> map) {
		Object source = map.get("source");
		if(source==null) { 
			throw new ServiceException("source为空异常");
		}
		//修改数
		BigDecimal bigCount = new BigDecimal(map.get("count").toString());
		if(source.toString().equals("2")) {
			List<PurchaseOrderDetailBean> purchaseOrderDetailBeans = new ArrayList<PurchaseOrderDetailBean>();
			OtherWarehouseBean otherWarehouseBean = otherWarehouseMapper.getOtherWarehouseById(map);
			if(otherWarehouseBean.getInOutType() == 1) {
				PurchaseOrderDetailBean podb=companyMaterialMapper.getPurchaseOrderDetailById(otherWarehouseBean.getPurchaseDetailId());
				//采购数
				BigDecimal bigPurchaseCount = new BigDecimal(podb.getPurchaseCount().toString());
				//采购入库数
				BigDecimal bigInCount = new BigDecimal(podb.getInCount().toString());
				//上次入库数
				BigDecimal oldInCount = new BigDecimal(otherWarehouseBean.getCount().toString());
				BigDecimal bigAllowUpdateCount = bigPurchaseCount.subtract(bigInCount).add(oldInCount);
				if(bigCount.subtract(bigAllowUpdateCount).doubleValue()>0) {
					throw new ServiceException("最大修改数为"+bigAllowUpdateCount.doubleValue());
				}else if(bigCount.subtract(bigAllowUpdateCount).doubleValue()==0) {
					podb.setIsFinish(1);
				}else {  
					podb.setIsFinish(0);
				}
				podb.setInCount(bigInCount.subtract(oldInCount).add(bigCount).doubleValue());
				purchaseOrderDetailBeans.add(podb);
				companyMaterialMapper.updatePurchaseOrderDetail(purchaseOrderDetailBeans);
			}else if(otherWarehouseBean.getInOutType() == 2) {//修改出库数量后,要关联修改投料单的receviceCount
				  Map<String,Object> purchaseMap = new HashMap<String,Object>();
				  purchaseMap.put("loginCompany",map.get("loginCompany"));
				  purchaseMap.put("purchaseDetailId", otherWarehouseBean.getPurchaseDetailId());
				  List<FeedOrderDetailBean> feedOrderDetailBeans = orderMapper.getFeedOrderDetailByPurchaseFeedDetailId(purchaseMap);
				  FeedOrderDetailBean feedOrderDetailBean = null; 
				  if(feedOrderDetailBeans!=null && feedOrderDetailBeans.size()>0) {
					  if(feedOrderDetailBeans.size()>1) { 
						  throw new ServiceException("查出两条库存信息异常");
					  }
					  feedOrderDetailBean = feedOrderDetailBeans.get(0);
				  }else {
					  throw new ServiceException("无库存数据异常");
				  } 
				  //要修改的投料单信息
				  List<FeedOrderDetailBean> feedList=new ArrayList<FeedOrderDetailBean>();
				  //通过出库数据查找投料单明细
				  //投料单投料数
				  BigDecimal bigFeedCount = new BigDecimal(feedOrderDetailBean.getFeedCount().toString());
				  //投料单领料数
				  BigDecimal bigReceiveCount = new BigDecimal(feedOrderDetailBean.getReceiveCount().toString());
				  //上次领料数
				  BigDecimal bigOldReceiveCount = new BigDecimal(otherWarehouseBean.getCount().toString());
				  //最大可领数(投料数-领料数+上次领料数)
				  BigDecimal bigAllowUpdateCount = bigFeedCount.subtract(bigReceiveCount).add(bigOldReceiveCount);
				  if(bigCount.subtract(bigAllowUpdateCount).doubleValue()>0) {
					  throw new ServiceException("最大修改数为"+bigAllowUpdateCount);
				  }  
				  feedOrderDetailBean.setReceiveCount(bigReceiveCount.subtract(bigOldReceiveCount).add(bigCount).doubleValue());
				  if(bigReceiveCount.subtract(bigOldReceiveCount).add(bigCount).subtract(bigFeedCount).doubleValue()==0) {
					  feedOrderDetailBean.setIsReceiveFinish(1);
				  }else {
					  feedOrderDetailBean.setIsReceiveFinish(0);
				  } 
				  feedList.add(feedOrderDetailBean);
				  purchaseMap.put("feedList", feedList);
				  companyMaterialMapper.updateFeedOrderDetailReceive(purchaseMap);
			}
			otherWarehouseBean.setCount(bigCount.doubleValue());
			otherWarehouseBean.setStatus(0);
			int updateRow = otherWarehouseMapper.updateOtherWarehouseByBeanOnStatus(otherWarehouseBean);
			if(updateRow<1) {
				throw new ServiceException("修改出入库数据异常");
			} 
			
		}else if(source.toString().equals("3")) {
			OtherWarehouseBean otherWarehouseBean = otherWarehouseMapper.getOtherWarehouseById(map);
			if(otherWarehouseBean.getInOutType()==1) {
				PurchaseDetailBean podb=companyMaterialMapper.getPurchaseDetailById(otherWarehouseBean.getPurchaseDetailId());
				//采购数
				BigDecimal bigPurchaseCount = new BigDecimal(podb.getPurchaseCount().toString());
				//采购入库数
				BigDecimal bigInCount = new BigDecimal(podb.getInCount().toString());
				//上次入库数
				BigDecimal oldInCount = new BigDecimal(otherWarehouseBean.getCount().toString());
				//最大修改数 采购单采购数-采购单入库数+上次采购入库数
				BigDecimal bigAllowUpdateCount = bigPurchaseCount.subtract(bigInCount).add(oldInCount);
				if(bigCount.subtract(bigAllowUpdateCount).doubleValue()>0) {
					throw new ServiceException("最大修改数为"+bigAllowUpdateCount.doubleValue());
				}else if(bigCount.subtract(bigAllowUpdateCount).doubleValue()==0) {
					podb.setIsFinish(1);
				}else {  
					podb.setIsFinish(0);
				}
				podb.setInCount(bigInCount.subtract(oldInCount).add(bigCount).doubleValue());
				companyMaterialMapper.updatePurchaseDetailOne(podb);
			}
			otherWarehouseBean.setCount(bigCount.doubleValue());
			otherWarehouseBean.setStatus(0);
			int updateRow = otherWarehouseMapper.updateOtherWarehouseByBeanOnStatus(otherWarehouseBean);
			if(updateRow<1) {
				throw new ServiceException("修改出入库数据异常");
			}
			
		}
	}
 

	
	
	/**
	 * 获取成品仓数据
	 * @param orderId(订单编号)
	 * @returnl
	 * @author nate
	 * @throws ServiceException
	 */
	public DatatablesViewPageBean<FinishStockBean> getFinishStockCount(Map map) {
		DatatablesViewPageBean<FinishStockBean>  datatablesViewPageBean=new DatatablesViewPageBean<FinishStockBean>();
		int  count=otherWarehouseMapper.getFinishStockCountCount(map);
		
		
		 //获取此订单明细加成品仓库存数
		 List<FinishStockBean> returnList=new ArrayList<FinishStockBean>();
		 List<FinishStockBean> finishStockBeanList=otherWarehouseMapper.getFinishStockBean(map);
		 Assert.isTrue(finishStockBeanList!=null && finishStockBeanList.size()>0 ,"此订单不存在");
//		 遍历订单明细,获取明细条数和成品仓有库存的数据
		 Set countSet=new HashSet<>();
		 for(FinishStockBean finishStockBean:finishStockBeanList) {
			 if(finishStockBean.getListMaterial().size()>0) {
				 countSet.add(finishStockBean.getListMaterial().size());
			 }
//			 if(finishStockBean.getStockCount()>0) {
				 returnList.add(finishStockBean);
//			 }
		 }
		 //库存单的库存信息
		 if(map.get("orderId") != null && !"".equals(map.get("orderId").toString())) {
			 List<FinishStockBean> finishStockList=new ArrayList<FinishStockBean>();
			 //当此订单的明细条数有且都大于0的时候才查询相似库存单
			 if(countSet.size()>0) {
				 map.put("countSet", countSet);
				 //获取相似库存单库存数
				 finishStockList=otherWarehouseMapper.getSimilarFinishStockData(map);
				 for(FinishStockBean finishStockBean:finishStockList) {
					 //如果本行有库存数,并且有物料颜色，比对物料和颜色
					 if(finishStockBean.getStockCount()>0 && finishStockBean.getListMaterial().size()>0) {
						 //finishStockBean为库存单的某一行数据  只要跟订单的某一行相匹配，则返回
						 for(FinishStockBean thisBean:finishStockBeanList) {
							 //如果本订单行有库存有物料，并且物料匹配的上
							 if(thisBean.getListMaterial().size()>0 &&   finishStockBean.getListMaterial().size()==thisBean.getListMaterial().size()) {
//							 if(  thisBean.getStockCount()>0 && thisBean.getListMaterial().size()>0 &&   finishStockBean.getListMaterial().size()==thisBean.getListMaterial().size()) {
								 List<QueryOrderPageBean> one=new ArrayList<QueryOrderPageBean>(finishStockBean.getListMaterial());
								 List<QueryOrderPageBean> two=new ArrayList<QueryOrderPageBean>(thisBean.getListMaterial());
								 if(checkEqual(one,two)) {
									 returnList.add(finishStockBean);
								 }
							 }
						 }
					 }
				 }
			 }
		 }
		 Assert.isTrue(returnList!=null && returnList.size()>0 ,"此订单没有库存");
		 datatablesViewPageBean.setReturnData(returnList);
		 datatablesViewPageBean.setiTotalRecords(count);
		 datatablesViewPageBean.setiTotalDisplayRecords(count);
		 return datatablesViewPageBean;
	}

	//判定行物料相等
	private boolean checkEqual(List<QueryOrderPageBean> stockMaterial, List<QueryOrderPageBean> thisMaterial) {
		if(stockMaterial.size()==0) {
			return true;
		}else {
			QueryOrderPageBean xx=stockMaterial.get(0);
			boolean bool=false;
			for(QueryOrderPageBean queryOrderPageBean:thisMaterial) {
				//如果物料类型其中有一行匹配到，则判定通过，并移除此行
				if(queryOrderPageBean.getColor().equals(xx.getColor()) && queryOrderPageBean.getMaterialType().equals(xx.getMaterialType())) {
					bool=true;
					thisMaterial.remove(queryOrderPageBean);
					break;
				}
			}
			if(bool) {
				stockMaterial.remove(0);
				return checkEqual(stockMaterial,thisMaterial);
			}else {
				return false;
			}
		}
	}

	
	/**
	 * 成品仓出库
	 * @param orderId(实际出库订单编号)
	 * @param type(类型 1 本订单  2 库存单)
	 * @param otherOrderId(其他订单编号  当类型不为1的时候有)
	 * @param rowIndexs(行号)
	 * @param remark(备注)
	 * @param outCount(出库数)
	 * @param customerName(客户名称)
	 * @param inOutUnit(出库单位)
	 * @param inCountPrice(出库单价)
	 * @author nate
	 * @param request 
	 * @throws CloneNotSupportedException 
	 * @throws ServiceException
	 */
	public String finishStockOut(Map map, HttpServletRequest request) throws CloneNotSupportedException {
		Assert.notNull(map.get("orderId"),"未获取到订单编号");
		Assert.notNull(map.get("type"),"未获取到类型");
		Assert.notNull(map.get("otherOrderId"),"未获取到库存订单编号");
		Assert.notNull(map.get("rowIndexs"),"未获取到行号");
		Assert.notNull(map.get("remark"),"请输入备注");
		Assert.notNull(map.get("outCount"),"请输入出库数");
		Assert.notNull(map.get("customerName"),"请选择客户名称");
		Assert.notNull(map.get("inCountPrice"),"请输入出库单价");
        CustomerBean customerBean=otherWarehouseMapper.getCustomerBeanByCustomerName(map.get("customerName").toString(),map.get("loginCompany").toString());
        Assert.notNull(customerBean,map.get("customerName").toString()+"客户不存在");
        int type=Integer.parseInt(map.get("type").toString());
		//出库数
		long outCount=Long.parseLong(map.get("outCount").toString());
		//获取本订单/库存单本行的库存数   入库数审核，出库数不审核
		long stockCount=otherWarehouseMapper.getOrderStockRowCount(map);
		Assert.isTrue(stockCount>=outCount,"有效库存为："+stockCount+",请检查是否有出库记录未审核");
		//获取本订单本行的订单数
		long orderRowCount=otherWarehouseMapper.getOrderRowCount(map);
		//获取本订单本行已经出库数,不分审核还是未审核
		map.put("status", 7);
		long orderRowAleradyOutCount=otherWarehouseMapper.orderRowAleradyOutCount(map);
		Assert.isTrue(orderRowAleradyOutCount+outCount<=orderRowCount,"本订单或其他订单已出库和为："+orderRowAleradyOutCount+",最多还可出库"+(orderRowCount-orderRowAleradyOutCount));
		//如果出库数相加正好等于订单数，则校验订单总数是否出库完成，如果全部出库完成，设置订单生产完成
//		if(orderRowAleradyOutCount+outCount==orderRowCount) {
//			checkOrderFinish(map.get("orderId").toString(),outCount);
//		}
		String ckId = dingTalkMapper.getApprovalNo("CK");
//		String prefix = BasicDataService.getPYIndexStr(map.get("loginCompany").toString(), true);
		map.put("id",ckId); 
		if(type==1) {//如果是本订单
			Object  inOutType=map.get("inOutType");
			if(map.get("inOutType")!=null) {
				map.put("type", map.get("inOutType"));
			}else {
				map.put("type", "9");
			}
			otherWarehouseMapper.insertOtherWarehouseByFinish(map);
		}else if(type==2) {//如果是库库存单
			map.put("otherId", StringUtil.getUUID());
			otherWarehouseMapper.FinishOtherStockOut(map);
			map.put("orderId", map.get("otherOrderId"));
			otherWarehouseMapper.insertOtherWarehouseByFinish(map);
		}else {//其他情况
			throw new ServiceException("类型不正确");
		}
		//需要校验是否有库存盘点没有审核,暂时没做
		//是否是过账审核
		String msString="";
        boolean isAduit=Boolean.parseBoolean(map.get("isAduit")==null?"fasle":map.get("isAduit").toString());
        if(isAduit) {
        	Map<String,String> aduitMap=warehouseService.setAduitMap(map);
        	aduitMap.put("id", ckId);
			warehouseService.approvalWarehouse(aduitMap,1,request);
        }else {
        	String queryCondition = "?ids="+ckId;
        	msString=companyMaterialService.sendWechatMessage("成品出库给客户", 2, "成品出库给客户", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), map, RedirectUrlUtil.queryWarehouse+queryCondition, 2);
        }
		return msString;
	}


	/**
	 * 校验订单是否全部出库，是则设置订单生产完成
	 * @param orderId(订单编号)
	 * @param outCount(本次出库数)
	 */
	private void checkOrderFinish(String orderId, double outCount) {
           Map  map=new HashMap();
           map.put("orderId", orderId);
	       	//获取本订单已经出库数
	   		long orderRowAleradyOutCount=otherWarehouseMapper.orderRowAleradyOutCount(map);
	   		//获取生产订单主表里的订单总数
	   		long orderCount=otherWarehouseMapper.getOrderCount(map);
	   		//已出库数+本次出库数>=订单数   （订单已全部出库） 将订单生产状态设置为生产完成
	   	    if(orderRowAleradyOutCount+outCount>=orderCount) {
	   	    	otherWarehouseMapper.setOrderFinish(map);
	   	    }
	}

	
	
	
	
	/**
	 * 出库至客户
	 * @natelu
	 */
	
	/**
	 * 查询所有的查询条件   八要素+仓库
	 * @param request
	 * @return
	 * @throws ServiceException
	 废弃
	public Set<SearchWhereBean> getAllSearchWhere(Map map) {
		return otherWarehouseMapper.rawMaterialSet(map);
	}
 */
	/**
	 * 
	 * @param map
	 * @return
	 */
	public Map getAllSearchWhere(Map map) {
        List<SearchWhereBean> materialSet=otherWarehouseMapper.getAllMaterialSearchWhere(map);
        List<SearchWhereBean> orderSet=otherWarehouseMapper.getAllOrderSearchWhere(map);
        Map returnMap=new HashMap<>();
        returnMap.put("materialSet", materialSet);
        returnMap.put("orderSet", orderSet);
		return returnMap;
	}
	
	
	public List<SearchWhereBean> getAllOrderSearchWhere(Map map){
		return otherWarehouseMapper.getAllOrderSearchWhere(map);
	}
	
	/**
	 * 查询所有的查询条件   四要素+仓库
	 * @param type(仓库  1 成品  2 报废 3 待处理 4 原料仓)
	 * @param request
	 * @return
	 * @throws ServiceException
	 */
	public DatatablesViewPageBean getAllOutData(Map map,int type) {
		Assert.notNull(type,"未获取到类型");
		List<SearchWhereBean> returnList=new ArrayList<SearchWhereBean>();
		int count=0;
		if(type==4) {//是原材料
			returnList=otherWarehouseMapper.getAllOutMaterialData(map);
			count=otherWarehouseMapper.getAllOutMaterialDataCount(map);
		}else {
			returnList=otherWarehouseMapper.getAllOutOtherMaterialData(map);
			count=otherWarehouseMapper.getAllOutOtherMaterialDataCount(map);
		}
		DatatablesViewPageBean<SearchWhereBean> datatablesViewPageBean=new DatatablesViewPageBean<SearchWhereBean>();
		datatablesViewPageBean.setReturnData(returnList);
		datatablesViewPageBean.setiTotalDisplayRecords(count);
		datatablesViewPageBean.setiTotalRecords(count);
		return datatablesViewPageBean;
	}

	
	/**
	 * 物料出库
	 * @param request 
	 * @param request
	 * @param materialArray(参数字符串数组)
	 * @param materialCode(物料代码)
	 * @param customerName(客户名称)
	 * @param inOutUnit(出库单位)
	 * @param inCountPrice(出库单价)
	 * @param count(出库数量)
	 * @param remark(备注)
	 * @param warehouseType(仓库类型)
	 * @return
	 * @throws CloneNotSupportedException 
	 * @throws ServiceException
	 */
	public String materialOutToCustomer(Map map, HttpServletRequest request) throws CloneNotSupportedException {
        Assert.notNull(map.get("materialArray"),"未获取到参数");
        String materialArray=map.get("materialArray").toString();
        JSONArray jsonArray=JSONArray.fromObject(materialArray);
        List<OtherWarehouseBean> otherList=(List<OtherWarehouseBean>) JSONArray.toCollection(jsonArray, OtherWarehouseBean.class);
        Assert.isTrue(otherList.size()>0,"未获取到出库行");
        List<String> idList = new ArrayList<String>();
        for(OtherWarehouseBean otherWarehouseBean:otherList) {
        	otherWarehouseBean.setId(dingTalkMapper.getApprovalNo("CK"));
        	Assert.isTrue(otherWarehouseBean.getWarehouseType()!=1,"成品请选择成品查询与出库");
        	CompanyMaterialTableBean companyMaterialTableBean=otherWarehouseMapper.getMaterialByMaterialCode(otherWarehouseBean.getMaterialCode());
            Assert.notNull(companyMaterialTableBean,otherWarehouseBean.getMaterialCode()+"物料不存在");
            CustomerBean customerBean=otherWarehouseMapper.getCustomerBeanByCustomerName(otherWarehouseBean.getCustomerName(),map.get("loginCompany").toString());
            Assert.notNull(customerBean,otherWarehouseBean.getCustomerName()+"客户不存在");
            Map<String, Double> resultMap=otherWarehouseMapper.getCountResult(otherWarehouseBean.getMaterialCode(),map.get("loginCompany").toString());
            Assert.isTrue(resultMap.get("purchaseCount")+resultMap.get("stockCount")-resultMap.get("feedCount")>=otherWarehouseBean.getCount(),otherWarehouseBean.getMaterialCode()+"物料库存不足或库存被占用");
            //获取原材料和辅料仓的物料合计
            map.put("materialCode", otherWarehouseBean.getMaterialCode());
			CompanyMaterialCountBean companyMaterialCountBean = companyMaterialCountService.getCompanyMaterialCountByMaterial(map);
            WarehouseInOutDetailBean warehouseInOutDetailBean = new WarehouseInOutDetailBean();
            warehouseInOutDetailBean.setCount(otherWarehouseBean.getCount());
            warehouseInOutDetailBean.setInOutUnit(otherWarehouseBean.getInOutUnit());
            warehouseService.checkMaterialCount(companyMaterialCountBean,companyMaterialTableBean,warehouseInOutDetailBean);
            idList.add(otherWarehouseBean.getId());
        }
        map.put("otherList", otherList);
        otherWarehouseMapper.materialOutToCustomer(map);
        String mString="";
        //是否是过账审核
        boolean isAduit=Boolean.parseBoolean(map.get("isAduit")==null?"fasle":map.get("isAduit").toString());
        if(isAduit) {
        	Map<String,String> aduitMap=warehouseService.setAduitMap(map);
        	for(OtherWarehouseBean otherWarehouseBean:otherList) {
        		aduitMap.put("id", otherWarehouseBean.getId());
				warehouseService.approvalWarehouse(aduitMap,1,request);
        	}
        }else {
        	String queryCondition = "?ids="+idList.toString().substring(1,idList.toString().length()-1).replace(" ","");
        	mString=companyMaterialService.sendWechatMessage("原材料出库给客户", 2, "原材料出库给客户", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), map, RedirectUrlUtil.queryWarehouse+queryCondition, 2);
        }
        return mString;
	}

	
	/**
	 * @param orderId(订单编号)
	 * @param rowIndexs(行号)
	 * @param request
	 * @return
	 */
	public List<FinishStockBean> getOrderFinishOutDetail(Map map) {
		Assert.notNull(map.get("rowIndexs"),"未获取到行号");
		Assert.notNull(map.get("orderId"),"未获取到订单编号");
		return otherWarehouseMapper.getOrderFinishOutDetail(map);
	}
 

}
